
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.util.Random;

import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;



@SuppressWarnings("serial")
public class ml extends JPanel implements MouseListener {

	//create containers for reference objects
	Main m;
	Surf s;
	JLabel l;
	Point p;
	Point p2;
	Universe u;
	Random r = new Random();
	dataSources d = new dataSources();
	
	int totalColourSchemes = 4		+1;
	
	int myFunction = 0;  	//reference for current mouse function on click
	int functionType = 0;	//Determines subclass of functions to execute, like a menu.
	
	int fcnt = 5;			//total number of mouse functions to iterate through
	int fnctype = 4;		//tot number of function catagorys
	
	int mwPos = 0;			//Everyone references the MW cycle
	int mwMax = fcnt;		//default position in the MW cycle, will change frequently
	int cycleNum = 0;		//for Mousewheel to identify which type to cycle
	
	int blockVal = 1;
	int blockSize = 16;
	int seedVal = 1;
	int seedRand = 6;
	int seedRndVar = 1;
	int toolRand = 1;
	int toolVar = 1;
	int colourScheme = -1;
	
	int copyPasteBlockSize = 16;
	
	boolean resetVal = true;
	
	int squareTest_BlockNum = 1;
	boolean bStepFrame = false;
	
	//constructor
    public ml(Main mm, Surf ss, JLabel ll) {
    	//System.out.println("ml");
    	m=mm;
    	s=ss;
    	l=ll;
        m.addMouseListener(this);
      
        functionType = 0;  
        
    }
  
    
    public void mousePressed(MouseEvent e) {
    	//refresh();
    	//get location information from mouse & jframes
    	p = MouseInfo.getPointerInfo().getLocation();
    	p2 = m.getLocation();
    	int mx =(p.x - p2.x - 2  - s.getX());
    	int my =(p.y - p2.y - 24 - m.getJMenuBar().getHeight() - s.getY());

    	
    	
    	//Left Click
    	 if((e == null || e.getButton() == MouseEvent.BUTTON1) && (mx >= 0 && my > 0) && (mx < s.getWidth() && my < s.getHeight()+1) ) {

	    	if(functionType == 0) {
	    		
	    		if (myFunction == 0) { //Place Block Small
	    			if(blockSize < 0) {blockSize=1;}
	    			if(toolRand <= 0) {toolRand=1;}
	    			if(toolVar <= 0) {toolVar=1;}
	    			if(resetVal) {blockVal = 1;resetVal=false;}
	    			placeBlock(mx, my, 0);
	        	}
	    		
	    		if (myFunction ==  1) { //Place Block Small
	    	    	if(blockSize < 0) {blockSize=3;}
	    			if(toolRand <= 0) {toolRand=1;}
	    			if(toolVar <= 0) {toolVar=1;}
	    			if(resetVal) {blockVal = 1;resetVal=false;}
    				placeBlock(mx, my, 0);
	        	}
	    		
	    		if (myFunction ==  2) { //Place block medium 
	    	    	if(blockSize < 0) {blockSize=8;}
	    			if(toolRand <= 0) {toolRand=1;}
	    			if(toolVar <= 0) {toolVar=1;}
	    			if(resetVal) {blockVal = 1;resetVal=false;}
					placeBlock(mx, my, 0);
	        	}
	    		
	    		if (myFunction ==  3) { //Place Block Big
	    	    	if(blockSize < 0) {blockSize=14;}
	    			if(toolRand <= 0) {toolRand=1;}
	    			if(toolVar <= 0) {toolVar=1;}
	    			if(resetVal) {blockVal = 1;resetVal=false;}
					placeBlock(mx, my, 0);
	        	}
	    		
	    		if (myFunction ==  4) { //Place Block Bigger
	    	    	if(blockSize < 0) {blockSize=32;}
	    			if(toolRand <= 0) {toolRand=1;}
	    			if(toolVar <= 0) {toolVar=1;}
	    			if(resetVal) {blockVal = 1;resetVal=false;}
					placeBlock(mx, my, 0);
	        	}
	    	}
	
	    	//Function type/catagory 1's options
	    	if(functionType == 1) {
	    		if (myFunction ==  0) { //chance block random Light			
	    			if(blockSize < 0) {blockSize=16;}
	    			if(toolRand <= 0) {toolRand=24;}
	    			if(toolVar <= 0) {toolVar=1;}
	    			if(resetVal) {blockVal=1;resetVal=false;}
					placeBlock(mx, my, 0);
	    		}
	    		
	    		if (myFunction ==  1) { //chance block random Heavy
	    			if(blockSize < 0) {blockSize= 16;}
	    			if(toolRand <= 0) {toolRand=12;}
	    			if(toolVar <= 0) {toolVar=32;}
	    			if(resetVal) {blockVal=-16;resetVal=false;}
					placeBlock(mx, my, 0);
	    		}
	    		
	    		if (myFunction ==  2) { //Square Test
	    			blockSize=squareTest_BlockNum;
	    			squareTest_BlockNum++;
	    			toolRand=1;
	    			toolVar=1;
	    			blockVal = 1;
	    			resetVal=false;
	    			placeBlock(mx, my, 0);
	        	}
	    		
	    		if (myFunction ==  3) { //Place medium Block 2-step Stripes

	        	}
	    		
	    		if (myFunction ==  4) { 
	    			if(blockSize < 0) {blockSize=6;}
	    			if(toolRand <= 0) {toolRand=3;}
	    			if(toolVar <= 0) {toolVar=3;}
	    			if(resetVal) {blockVal=-1;resetVal=false;}
					placeBlock(mx, my, 0);
	        	}
	    		
	    	}
	    	
	    	//Function type/catagory 2's options
	    	if(functionType == 2) {
	    		
				

	    		if (myFunction ==  0) { //chance Set to 0, large
	    			if(blockSize < 0) {blockSize=1;}
	    			if(toolRand <= 0) {toolRand=1;}
	    			if(toolVar <= 0) {toolVar=1;}
	    			if(resetVal) {blockVal = 0;resetVal=false;}
					placeBlock(mx, my, 0);
	    		}
	    		
	    		if (myFunction ==  1) { //Set to 0, medium
	    			if(blockSize < 0) {blockSize=8;}
	    			if(toolRand <= 0) {toolRand=1;}
	    			if(toolVar <= 0) {toolVar=1;}
	    			if(resetVal) {blockVal = 0;resetVal=false;}
					placeBlock(mx, my, 0);
	    		}
	    		
	    		if (myFunction ==  2) { //Set to 0, large
	    			if(blockSize < 0) {blockSize=32;}
	    			if(toolRand <= 0) {toolRand=1;}
	    			if(toolVar <= 0) {toolVar=1;}
	    			if(resetVal) {blockVal = 0;resetVal=false;}
					placeBlock(mx, my, 0);
	    		}
	    		
	    		if (myFunction ==  3) { //Set to 0, large
	    			if(blockSize < 0) {blockSize=24;}
	    			if(toolRand <= 0) {toolRand=12;}
	    			if(toolVar <= 0) {toolVar=1;}
	    			if(resetVal) {blockVal = 0;resetVal=false;}
					placeBlock(mx, my, 0);
	    		}
	    		
	    		if (myFunction ==  4) { //Set to 0, large
	    			if(blockSize < 0) {blockSize=6;}
	    			if(toolRand <= 0) {toolRand=4;}
	    			if(toolVar <= 0) {toolVar=1;}
	    			if(resetVal) {blockVal = 0;resetVal=false;}
					placeBlock(mx, my, 0);
	    		}
	    		
	    	}

	    	if(functionType == 3) {
				if (myFunction ==  0) { 
					if(blockSize < 0) {blockSize= 16;}
	    			if(toolRand <= 0) {toolRand=12;}
	    			if(toolVar <= 0) {toolVar=32;}
	    			if(resetVal) {blockVal=-16;resetVal=false;}
					placeBlock(mx, my, 0);
				}

				if (myFunction ==  1) { 
					blockSize=copyPasteBlockSize;
	    			if(toolRand <= 0) {toolRand=1;}
	    			if(toolVar <= 0) {toolVar=1;}
	    			placeData(mx, my, 0);
				}
				
				if (myFunction ==  2) { 
					blockSize=copyPasteBlockSize;
	    			if(toolRand <= 0) {toolRand=1;}
	    			if(toolVar <= 0) {toolVar=1;}
	    			captureData(mx, my, 0);
				}
				
			}
	    	
    	}

    	//Right Click - Pause controller
    	if(e != null && e.getButton() == MouseEvent.BUTTON3) { 
    		if(bStepFrame) {stepFrames();} else {toggleStart();}
    	}
    	
    	//middle click: erase layer
    	if(e != null && e.getButton() == MouseEvent.BUTTON2){
    		eraseLayer();
    		squareTest_BlockNum = 1;
    	}
    	
    	refresh();
    }

    
    //identifies the mousefunction action that is highlighted
    public void updateListing(){

    	//convert pause state to string
    	String tmps = "";
    	if(s.paused == true) {tmps+="1";} else {tmps+="0";}
    	if(s.upaused == true) {tmps+="1";} else {tmps+="0";}

    	l.setText(
    			
    			"<html><font size=1><font face=courier>" 		+ 
    			
    			s.zdraw 			+" Z-Layer<br>" 			+ 
    			tmps 				+" Pause Status<br>" 		+    
    			functionType 		+" Tool<br>"				+ 
    			myFunction 			+" SubTool<br>" 			+
    			mwPos 				+" MsWheel Raw#<br>" 		+  
    			cycleNum 			+" MouseWheel<br>" 			+ 
    			blockSize 			+" Block Size<br>" 			+ 
    			blockVal 			+" Block Value<br>" 		+ 
    			
    			" </font></html>"	
    			
    	);
    	
    }
    
    //called during initial program configuration, or to pause/unpause on right click
    public void toggleStart() {
    	
    	if(s.upaused ) { s.upaused = false; } else { s.upaused = true; }
		if(s.paused ) { s.paused = false; } else { s.paused = true; }
		
		//refresh();
    }
    
    public void stepFrames() {
    	
    	s.stepFrames = 1;
		
		//refresh();
    }
    
    public void autoZ() {
        s.zdraw++;
    	s.zdraw = s.zdraw % s.zz;
    }
    
    //called from class mwl, scrolls subfunction on mousewheel event
    public void mouseWheelScrolled(int mw_rotation) {

    	if(mw_rotation == -1) { 
			mwPos++;
			mwPos=mwPos%mwMax; 
		}
    	
    	if(mw_rotation == 1) { 
			mwPos+=(mwMax-1);
			mwPos=mwPos%mwMax; 
		}
    	
    	squareTest_BlockNum = 1;
    	
    	setCycle();
    	
    	refresh();
    }
    
    public void setCycle(){
    	if(cycleNum == 0) {myFunction = mwPos;blockSize = -1;toolRand = -1;toolVar = -1;resetVal = true;}
    	if(cycleNum == 1) {s.zdraw = mwPos;}
    	if(cycleNum == 3) {blockSize = mwPos;}
    	if(cycleNum == 4) {blockVal = ((mwPos+150)%300)-150;}
    	if(cycleNum == 7) {cycleColourSchemes(); }
    	refresh();
    }
    
    private void cycleColourSchemes(){
    	s.colourScheme = mwPos-1;
    } 

    
    
    public void eraseAll(){
    	for(int i = 0; i < s.zz; i++) {
    		s.u.resetArZ(0,i);
    	}
    	refresh();
    }
    
    public void eraseLayer(){
    	for(int i = 0; i < s.zz; i++) {
    		s.u.resetArZ(0, s.zdraw);
    	}
    	refresh();
    }
    
    public void reseedAll(int rand, int val) {
    	eraseAll();
    	s.u.a.seedAll(seedRand, seedVal, seedRndVar);
    	refresh();
    }
    
    public void reseedLayer(int rand, int val) {
    	eraseLayer();
    	s.u.a.seedZ(rand, s.zdraw, val, seedRndVar);
    	refresh();
    }
    
    public void refresh() {
    	//updates menu listing
		updateListing();
    	
    	//This makes blocks placed while paused visible
    	if(s.upaused) {
    		if(s.paused) { 
    			s.paused = false; 
    		} 
    	}
    	
    	//refreshes elements that may have been altered
    	s.repaint();
    }
    
    //sets the tool
    public void setFunctionType(int funct) {
     	functionType=funct;
     	refresh();
    }
   

    //sets the seeding parameters
    public void dialogReseed(){
    	String str = JOptionPane.showInputDialog(m, "Seed, with chance one out of:", String.valueOf(seedRand));
    	String str2 = JOptionPane.showInputDialog(m, "Set cell value:", String.valueOf(seedVal));
    	String str3 = JOptionPane.showInputDialog(m, "Set random variation in value:", seedRndVar);
    	if(str != null && str2 != null) {
    		seedRand = Integer.parseInt(str);
    		seedVal = Integer.parseInt(str2);
    		seedRndVar = Integer.parseInt(str3);
    		//reseedAll(seedRand, seedVal);
    		reseedLayer(seedRand,seedVal);
    	}
    }


    
    public void dialogSetBlockVal() {
    	String str = JOptionPane.showInputDialog(m, "Tool Value:", 1);
    	if(str != null) {
    		blockVal = Integer.parseInt(str);
    	}
	}

    public void dialogSetBlockRand() {
    	String str = JOptionPane.showInputDialog(m, "Tool Placement - Random Distribution:", 6);
    	if(str != null) {
    		toolRand = Integer.parseInt(str);
    	}
	}
    
    public void dialogSetBlockVar() {
    	String str = JOptionPane.showInputDialog(m, "Tool Value - Random Variation:", 1);
    	if(str != null) {
    		toolVar = Integer.parseInt(str);
    	}
	}
    
    public void dialogSetBlockSize() {
    	String str = JOptionPane.showInputDialog(m, "Tool Size:", 20);
    	if(str != null) {
    		blockSize = Integer.parseInt(str);
    	}
    }
    
    public void placeBlock(int mx, int my, int mz){
	    if(mx-(blockSize/2) >= 0 && my-(blockSize/2) > 0 && mx+(blockSize/2) < s.getWidth() && my+(blockSize/2) < s.getHeight()+1) {
			for(int i = 0; i < blockSize; i++){
				s.u.a.plcLn(	
					mx-blockSize, 
					(my+i)-blockSize, 
					s.zdraw, 
					
					toolRand, 0, blockVal, 1, 0, mx+blockSize, blockSize, toolVar
				);
			} 
	    }
    }
    
    public void placeData(int mx, int my, int mz){
	    if(mx-(blockSize/2) >= 0 && my-(blockSize/2) > 0 && mx+(blockSize/2) < s.getWidth() && my+(blockSize/2) < s.getHeight()+1) {
			for(int i = 0; i < blockSize; i++){
				s.u.a.plcDataLn(	
					mx-blockSize, 
					(my+i)-blockSize, 
					s.zdraw, 
					
					toolRand, 0, 0, 1, 0, mx+blockSize, blockSize, toolVar, d, 1
				);
			} 
			d.reset();
	    }
    }

    
    public void captureData(int mx, int my, int mz){
		int[][][] resultAr;
		resultAr = new int[blockSize][blockSize][1];
		
		//String ss = "";
		//use block placement descendent as capture device for u.universe
		
	    if(mx-(blockSize/2) >= 0 && my-(blockSize/2) > 0 && mx+(blockSize/2) < s.getWidth() && my+(blockSize/2) < s.getHeight()+1) {
			for(int i = 0; i < blockSize; i++){
				int[] intar = new int[blockSize];
				intar = s.u.a.getDataLn(	
					mx-blockSize, 
					(my+i)-blockSize, 
					s.zdraw, 
						
					toolRand, 0, 0, 1, 0, mx+blockSize, blockSize, toolVar
				);
				
				
				
				for (int j = 0; j < intar.length; j++){
					resultAr[j][i][0] = intar[j];
		    	    //ss+=intar[j] + ",";
			    }
				//ss+="\n";
			} 
			//System.out.println(ss);
			 	
				
	    }
	    
	    
	   // ss="";
	    /*for (int i = 0; i < resultAr.length; i++){
	    	for (int j = 0; j < resultAr[0].length; j++){
	    	    ss+=resultAr[i][j][0] + ",";
		    }
	    	ss+="\n";
	    }*/
	    //System.out.println(ss);
	    
	    
	    d.setArray(resultAr);
    }

    
    //implicit function storage
    ////////////////////////////////////////////
    public void mouseReleased(MouseEvent e) {    }
    public void mouseEntered(MouseEvent e) {    }
    public void mouseExited(MouseEvent e) {    }
    public void mouseClicked(MouseEvent e) {    }
    ////////////////////////////////////////////


	
}